# Copyright (c) 2007 John Rollin Wulff <johnw@orcasnet.com>
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
module ValidationAssertions
  # Asserts that a given model validates the presence of a given field.
  def assert_validates_presence_of(model, field)
    record = model.new
    assert_error_for_field_includes record, field, "can't be blank"
  end
  
  # Asserts that a field for a model validates a minimum length.
  def assert_validates_minimum_length_of(model, field, length)
    record = model.new field => "#{x = '';(length - 1).times { x += 'X' };x}"
    assert_error_for_field_includes record, field, "is too short (minimum is #{length} characters)"
  end
  
  # Asserts that a field for a model validates a maximum length.
  def assert_validates_maximum_length_of(model, field, length)
    record = model.new field => "#{x = '';(length + 1).times { x += 'X' };x}"
    assert_error_for_field_includes record, field, "is too long (maximum is #{length} characters)"
  end
  
  # Asserts that a field for a record must be unique to validate.
  def assert_validates_uniqueness_of(model, field)
    model.new(field => 'taken').save_with_validation(false)
    record = model.new field => 'taken'
    assert_error_for_field_includes record, field, 'has already been taken'
  end
  
  # Asserts that a field for a record generates a given error on save.
  def assert_error_for_field_includes(record, field, error)
    assert_raises(ActiveRecord::RecordInvalid) { record.save! }
    assert_not_nil record.errors, "#{record.class} did not raise any errors."
    assert_not_nil record.errors[field], "#{record.class}.#{field} did not raise any errors."
    assert record.errors[field].include?(error), "#{record.class}.errors[:#{field}] expected to include \"#{error}\" but was #{record.errors[field].inspect}"
  end
end